package org.ipp4j.core.standard;

/**
 * <p>
 * As value-tag value in IPP RFC Standard.
 * 
 * @author cko
 * 
 */
public enum Tag {

	/**
	 * Invalid tag name
	 */
	CUPS_INVALID(-1),

	/**
	 * Zero tag - used for separators
	 */
	ZERO(0x00),

	/**
	 * Operation group
	 */
	OPERATION(0x01),

	/**
	 * Job group
	 */
	JOB(0x02),

	/**
	 * End-of-attributes
	 */
	END(0x03),

	/**
	 * Printer group
	 */
	PRINTER(0x04),

	/**
	 * Unsupported attributes group
	 */
	UNSUPPORTED_GROUP(0x05),

	/**
	 * Subscription group
	 */
	SUBSCRIPTION(0x06),

	/**
	 * Event group
	 */
	EVENT_NOTIFICATION(0x07),

	/**
	 * Resource group
	 */
	RESOURCE(0x08),

	/**
	 * Document group
	 */
	DOCUMENT(0x09),

	/**
	 * Unsupported value
	 */
	UNSUPPORTED_VALUE(0x10),

	/**
	 * Default value
	 */
	DEFAULT(0x11),

	/**
	 * Unknown value
	 */
	UNKNOWN(0x12),

	/**
	 * No-value value
	 */
	NOVALUE(0x13),

	/**
	 * Not-settable value
	 */
	NOTSETTABLE(0x15),

	/**
	 * Delete-attribute value
	 */
	DELETEATTR(0x16),

	/**
	 * Admin-defined value
	 */
	ADMINDEFINE(0x17),

	/**
	 * Integer value
	 */
	INTEGER(0x21),

	/**
	 * Boolean value
	 */
	BOOLEAN(0x22),

	/**
	 * Enumeration value
	 */
	ENUM(0x23),

	/**
	 * Octet string value
	 */
	STRING(0x30),

	/**
	 * Datetime value
	 */
	DATE(0x31),

	/**
	 * Resolution value
	 */
	RESOLUTION(0x32),

	/**
	 * Range value
	 */
	RANGE(0x33),

	/**
	 * Beginning of collection value
	 */
	BEGIN_COLLECTION(0x34),

	/**
	 * Text-with-language value
	 */
	TEXTLANG(0x35),

	/**
	 * Name-with-language value
	 */
	NAMELANG(0x36),

	/**
	 * End of collection value
	 */
	END_COLLECTION(0x37),

	/**
	 * Text value
	 */
	TEXT(0x41),

	/**
	 * Name value
	 */
	NAME(0x42),

	/**
	 * Reserved for future string value
	 */
	RESERVED_STRING(0x43),

	/**
	 * Keywood value
	 */
	KEYWORD(0x44),

	/**
	 * URI value
	 */
	URI(0x45),

	/**
	 * URI scheme value
	 */
	URISCHEME(0x46),

	/**
	 * Character set value
	 */
	CHARSET(0x47),

	/**
	 * Language value
	 */
	LANGUAGE(0x48),

	/**
	 * MIME media type value
	 */
	MIMETYPE(0x49),

	/**
	 * Collection member name value
	 */
	MEMBERNAME(0x4a),

	/**
	 * Extension point for 32-bit tags
	 */
	EXTENSION(0x7f);

	int code;

	Tag(int code) {
		this.code = code;
	}

	private static Tag[] GROUPS = { JOB, OPERATION, PRINTER, UNSUPPORTED_GROUP,
			SUBSCRIPTION, EVENT_NOTIFICATION, RESOURCE, DOCUMENT };

	public static Tag valueOf(byte code) {
		for (Tag tag : Tag.values()) {
			if (tag.code == code) {
				return tag;
			}
		}
		throw new IllegalArgumentException("tag code " + code
				+ " cannot be found.");
	}

	public boolean isGroupTag() {
		for (Tag groupTag : GROUPS) {
			if (groupTag == this) {
				return true;
			}
		}
		return false;
	}

	@Override
	public String toString() {
		return "[" + name() + "(" + Integer.toHexString(code) + ")]";
	}

	public byte toByte() {
		return (byte) code;
	}
}
